/*
 * @Author: 赵东选 1807248216@qq.com
 * @Date: 2024-10-20 11:42:27
 * @LastEditors: 赵东选 1807248216@qq.com
 * @LastEditTime: 2024-10-20 20:55:44
 * @FilePath: /9_int/bsp/clk/bsp_clk.c
 * @Description:
 *
 * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
 */
#include "bsp_clk.h"

/*
 * @description	: 使能I.MX6U所有外设时钟
 * @param 		: 无
 * @return 		: 无
 */
extern void clk_enable(void)
{
    CCM->CCGR0 = 0XFFFFFFFF;
    CCM->CCGR1 = 0XFFFFFFFF;
    CCM->CCGR2 = 0XFFFFFFFF;
    CCM->CCGR3 = 0XFFFFFFFF;
    CCM->CCGR4 = 0XFFFFFFFF;
    CCM->CCGR5 = 0XFFFFFFFF;
    CCM->CCGR6 = 0XFFFFFFFF;
}

void imx6u_clkinit()
{
    // 初始化6ULL的主频为528MHZ
    uint32_t reg = 0;
    if (((CCM->CCSR >> 2) & 0x1) == 0)
    {
        // CCM_CCSR_STEP_SEL(0);
        CCM->CCSR &= ~(1 << 8);
        // CCM_CCSR_PLL1_SW_CLK_SEL(1);
        CCM->CCSR |= (1 << 2);
    }

    // 设置PLL1 = 1056MHZ
    reg = CCM_ANALOG->PLL_ARM;
    reg &= ~(0x27f);
    reg |= 0x258;
    // CCM_ANALOG_PLL_ARM_DIV_SELECT(88)
    // CCM_ANALOG_PLL_ARM_ENABLE(1);
    CCM_ANALOG->PLL_ARM = reg;
    // CCM_CDHIPR_ARM_PODF_BUSY(x)
    while ((CCM->CDHIPR >> 16) & 0x1)
        ;
    // CCM_CACRR_ARM_PODF(1);
    CCM->CACRR &= ~(0x7);
    CCM->CACRR = 1; // 设置2分频
    // CCM_CCSR_PLL1_SW_CLK_SEL(x)
    CCM->CCSR &= ~(1 << 2);

    // 设置PLL2的4路PFD
    reg = 0;
    reg = CCM_ANALOG->PFD_528;
    reg &= ~(0x3f3f3f3f);
    // CCM_ANALOG_PFD_528_PFD3_FRAC(0x20)   PLL2_PFD3=297MHZ 528*18/PFD3_FRAC
    reg |= (0x20 << 24);
    // CCM_ANALOG_PFD_528_PFD2_FRAC(0x18)   PLL2_PFD2=396MHZ 528*18/PFD2_FRAC
    reg |= (0x18 << 16);
    // CCM_ANALOG_PFD_528_PFD1_FRAC(0x10)   PLL2_PFD1=594MHZ 528*18/PFD1_FRAC
    reg |= (0x10 << 8);
    // CCM_ANALOG_PFD_528_PFD0_FRAC(0x1b)   PLL2_PFD0=352MHZ 528*18/PFD0_FRAC
    reg |= (0x1b << 0);
    CCM_ANALOG->PFD_528 = reg;

    // 设置PLL3的4路PFD
    reg = 0;
    reg = CCM_ANALOG->PFD_480;
    reg &= ~(0x3f3f3f3f);
    // CCM_ANALOG_PFD_480_PFD3_FRAC(0x13)   PLL2_PFD3=454.7MHZ 480*18/PFD3_FRAC
    reg |= (0x13 << 24);
    // CCM_ANALOG_PFD_480_PFD2_FRAC(0x11)   PLL2_PFD2=508.2MHZ 480*18/PFD2_FRAC
    reg |= (0x11 << 16);
    // CCM_ANALOG_PFD_480_PFD1_FRAC(0x10)   PLL2_PFD1=540MHZ 480*18/PFD1_FRAC
    reg |= (0x10 << 8);
    // CCM_ANALOG_PFD_480_PFD0_FRAC(0xc)   PLL2_PFD0=720MHZ 480*18/PFD0_FRAC
    reg |= (0xc << 0);
    CCM_ANALOG->PFD_480 = reg;

    // 设置其他外设时钟源 AHB_CLK_ROOT PERCLK_CLK_ROOT IPG_CLK_ROOT

    // AHB_CLK_ROOT=132MHZ
    // CCM_CBCMR_PRE_PERIPH_CLK_SEL(0x1)
    CCM->CBCMR &= ~(0x3 << 18);
    CCM->CBCMR |= (0x1 << 18);
    // CCM_CDHIPR_PERIPH_CLK_SEL_BUSY(x)
    while ((CCM->CDHIPR >> 5) & 0x1)
        ;
    // CCM_CBCDR_PERIPH_CLK_SEL(0)
    CCM->CBCDR &= ~(0x1 << 25);
    // CCM_CDHIPR_AHB_PODF_BUSY(x)
    while ((CCM->CDHIPR >> 1) & (0x1))
        ;
    // CCM_CBCDR_AHB_PODF(0x2)
    CCM->CBCDR &= ~(0x7 << 10);
    CCM->CBCDR |= (0x2 << 10);

    // PERCLK_CLK_ROOT=66MHZ IPG_CLK_ROOT=66MHZ
    // CCM_CBCDR_IPG_PODF(0x1)
    CCM->CBCDR &= ~(0x3 << 8);
    CCM->CBCDR |= (0x1 << 8);

    // CCM_CSCMR1_PERCLK_CLK_SEL(0)
    CCM->CSCMR1 &= ~(0x1 << 6);
    // CCM_CSCMR1_PERCLK_PODF(0)
    CCM->CSCMR1 &= ~(0x3f << 0);
}
